// step 2 - http://en.wikipedia.org/wiki/Bzip2#Compression_stack

#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

#include "BWT.h"

bool equals(unsigned int bytes, const unsigned char *buf1, const unsigned char *buf2);

int main()
{
	const int BUFLEN = 1024*1024;	// 1MiB
	unsigned char *buffer = new unsigned char[BUFLEN];
	ifstream fin("text.txt", ios_base::in | ios_base::binary);
	if(!fin.is_open()) { cerr << "error" << endl; return 0; }
	ofstream fout("text.bwt", ios_base::out | ios_base::binary);
	if(!fout.is_open()) { cerr << "error" << endl; return 0; }
	//
	unsigned char *encoded = new unsigned char[BUFLEN], *decoded = new unsigned char[BUFLEN];
	unsigned int I;
	streamsize read;
	while(1)
	{
		// encode a single block
		fin.read((char *)buffer, BUFLEN);
		if((read = fin.gcount()) > 0)
		{
			//buffer[0] = 'a';buffer[1] = 'b';buffer[2] = 'c';buffer[3] = 'd';buffer[4] = 'e';buffer[5] = 'f';buffer[6] = 'g';read=7;
			BWT::Encode(read, buffer, encoded, I);
			fout.write((char *)&I, sizeof(unsigned int));
			fout.write((char *)encoded, read);
			BWT::Decode(read, encoded, I, decoded);
			if(equals(read, buffer, decoded))
				cout << "Ok" << endl;
			else
				cout << "Err" << endl;
		}
		if(fin.eof()) break;
	}
	//
	delete [] encoded;
	delete [] decoded;
	delete [] buffer;
	//
	fout.close();
	fin.close();
	return 0;
}

bool equals(unsigned int bytes, const unsigned char *buf1, const unsigned char *buf2)
{
	for(unsigned int i = 0; i < bytes; i++)
		if(buf1[i] != buf2[i])
			return false;
	return true;
}